package com.evil.kingdom.service.battle.impl;

import com.evil.kingdom.pojo.dto.person.base.PersonDto;
import com.evil.kingdom.pojo.entity.action.AbstractPosition;
import com.evil.kingdom.pojo.entity.action.Battle;
import com.evil.kingdom.pojo.entity.action.BattlePerson;
import com.evil.kingdom.pojo.enums.BattleTypeEnum;
import com.evil.kingdom.service.battle.BattleService;
import com.evil.kingdom.utils.DijkstraUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 自动战斗
 *
 * @author liyang
 * @date 2024-06-26 09:21
 */
@Slf4j
public class AutoBattleService implements BattleService {
    public static final Logger battleLogger = LoggerFactory.getLogger("KINGDOM_BATTLE_LOGGER");

    @Override
    public BattleTypeEnum type() {
        return BattleTypeEnum.AUTO;
    }

    @Override
    public double unit() {
        return 1;
    }

    @Override
    public double minUnit() {
        return 0.1;
    }

    @Override
    public void move(Battle battle) {
        battle.autoFindEnemy();
        AbstractPosition position = battle.getPosition();
        BattlePerson<?> person = battle.getPerson();
        BattlePerson<?> enemy = battle.getEnemy();
        if (null == enemy) {
            battle.setFlight(false);
            return;
        }
        PersonDto personBase = person.getBase();
        PersonDto enemyBase = enemy.getBase();
        double unit = this.unit();
        double step = personBase.getSpeed() * unit;
        double attackSpeed = personBase.getAttackSpeed() * unit;
        AbstractPosition enemyPosition = battle.getLayout().get(enemy);
        battleLogger.info("move|before|offensive:{}:{}, defensive:{}:{}, step:{}, flight:{}", personBase.getName(), position, enemyBase.getName(), enemyPosition, step, battle.getFlight());

        synchronized (person.hashCode() + "move") {
            DijkstraUtil.Slope slope;
            synchronized (enemy.hashCode() + "move") {
                slope = DijkstraUtil.calSlope(position, enemyPosition);
            }

            // 直线距离
            double weight = DijkstraUtil.calWeight(slope);
            battleLogger.info("move|check|offensive:{}:{}, defensive:{}:{}, weight:{}, attackSpeed:{}, flight:{}", personBase.getName(), position, enemyBase.getName(), enemyPosition, weight, attackSpeed, battle.getFlight());
            // 是否在攻击范围
            if (weight <= attackSpeed) {
                // 标识为攻击状态
                battle.setFlight(true);
                return;
            }

            // 自动计算步进
            AbstractPosition result = DijkstraUtil.offsetAI(position, enemyPosition, step, this.unit(), this.minUnit(), battle.getLayout());
            // 平移计算步进
            //AbstractPosition result = DijkstraUtil.offsetParallel(position, slope, step);
            if (null != result) {
                position.move(result);
            }
            battleLogger.info("move|after|offensive:{}:{}, defensive:{}:{}, step:{}, flight:{}", personBase.getName(), position, enemyBase.getName(), enemyPosition, step, battle.getFlight());
        }
    }
}
